﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;
using Core;
using Core.UIItems;
using Core.UIItems.ListBoxItems;
using Core.UIItems.WindowItems;


namespace UITestSuite
{
    /// <summary>
    /// Test suite for the forums subscription dialog window
    /// </summary>
    [TestFixture]
    public class SubscriptionDialogTests
    {
        #region Private Data
        private Application applicationUnderTest;
        private Window mainWindow;
        private Window subscriptionDialogWindow;
        private Button cancelButton;
        private Button finishButton;
        private ComboBox daysComboBox;
        private ComboBox brandComboBox;
        private ComboBox localeComboBox;
        private ComboBox showComboBox;
        private ListView availableForumsListBox;
        private ListView previewForumsListBox;
        private Button addButton;
        private Button removeButton;
        private TestParameters testParameters;
        private TextBox filterTextBox;
        private int expectedPreviewListCount = 0;

        #endregion

        #region NUnit setup and teardown methods
        /// <summary>
        /// Before each test, load test parameters, establish a known application state,
        /// launch the app, and get the main window
        /// </summary>
        [SetUp]
        public void Setup()
        {
            testParameters = new TestParameters();

            // Delete the database and user config file to get first time user conditions
            UITestHelperClass.DeleteUserConfigFile();
            UITestHelperClass.DeleteOfflineStore(testParameters.StandardDataStoreFolderName, testParameters.CustomDataStoreFileName);

            // After the user config file has been deleted, override the default for auto synch so that
            // auto synchronization does not try to run during the longer subscription tests
            DisableAutoSynch();

            // Start the application for the test
            StartApp();
        }

        /// <summary>
        /// If the test fails, it might leave the app running so we check and 
        /// shut it down (if necessary)in the teardown 
        /// </summary>
        [TearDown]
        public void TearDown()
        {
            if (applicationUnderTest.HasExited == false)
            {
                applicationUnderTest.Kill();
            }
        }

        #endregion

        #region Tests

        /// <summary>
        /// This test verifies that the user can successfully use the Filter Name and Description 
        /// textbox to reduce the number of forums presented in the Available Forums list. 
        /// </summary>
        [Test]
        public void FilteringByTextInNameAndDescription()
        {
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo );

            GetSubscriptionDialogControls();

            ChangeBrand("Msdn");

            // This section filters using strings that are in forum names. 
            // They may also be in the dsecription field but that's not the 
            // point of this part of the test

            filterTextBox.Text = "js";

            string[] scriptForums = { "JScript for the .NET Framework", };

            CheckExpectedForumNames(scriptForums, "js");

            filterTextBox.Text = "c#";

            string[] cSharpForums = { "Visual C# General", "Visual C# IDE", "Visual C# Language", };

            CheckExpectedForumNames(cSharpForums, "C#");

            string[] WPFForums = { "Visual Studio WPF Designer", "Windows Presentation Foundation (WPF)", "Working with Data in WPF Applications", };
            filterTextBox.Text = "wpf";
            CheckExpectedForumNames(WPFForums, "WPF");

            // This section uses a string that is found only in the Description field of some forums
            // So, if the expected forum names are found we demonstrate that the app is
            // searching on the Description field
            string[] descriptionContainsTechnique = { "Building Development and Diagnostic Tools for .Net", "Visual Studio Class Designer", };
            filterTextBox.Text = "technique";
            CheckExpectedForumNames(descriptionContainsTechnique, "technique");

            // No forums contain asdf in either name or Description
            filterTextBox.Text = "asdf";
            Assert.AreEqual(0, availableForumsListBox.Rows.Count, "Found some forums with asdf filter");

            // A common string generates a lot of results since it will match words
            // such as class, pass, as, etc as well as acronyms such as ASP.
            filterTextBox.Text = "as";
            Assert.LessOrEqual(42, availableForumsListBox.Rows.Count, "Expected at least 42 forums containing as, AS, aS, As");

            cancelButton.Click();

            ExitApp();
        }

        /// <summary>
        /// This test verifies the startup scenario behavior
        /// and verifies the default settings are as exepcted.
        /// </summary>
        [Test]
        public void NoSubscriptionsStartupScenario()
        {
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Subscription Dialog should start automatically after login 
            // because there are no subscriptions.
            GetSubscriptionDialogControls();

            Assert.IsNotNull(localeComboBox.SelectedItem);
            Assert.IsNull(brandComboBox.SelectedItem);
            Console.WriteLine("daysComboBox Selected Item == " + daysComboBox.SelectedItem.ToString());
            Assert.AreEqual("7", daysComboBox.SelectedItemText);
            Assert.AreEqual("All", showComboBox.SelectedItemText);
            Console.WriteLine("showComboBox Selected Item == " + showComboBox.SelectedItem);

            Assert.IsFalse(addButton.Enabled == true);
            Assert.IsFalse(removeButton.Enabled == true);
            Assert.AreEqual(0, availableForumsListBox.Rows.Count);
            Assert.AreEqual(0, previewForumsListBox.Rows.Count);
            subscriptionDialogWindow.Close();

            ExitApp();
        }

        /// <summary>
        /// This test verifies that the Subscribe button presents the Subscribe to Forums dialog,
        /// prompts an unauthenticated user and does not prompt an authenticated user.
        /// </summary>
        [Test]
        public void SubscribeButtonPresentsSubscribeToForumsDialog()
        {
            // Cancel logon so we are not authenticated
            UITestHelperClass.CancelLogon(mainWindow);

            // Click the subscribe button on the main window
            Button actionButton = mainWindow.Get<Button>("SubscribeButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // That should present the Logon dialog window again. So we logon
            // in order to get the Subscribe to Forums window
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo );

            // Find the Subscription Dialog window
            subscriptionDialogWindow = (Window)mainWindow.ModalWindow("Subscribe to Forums", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(subscriptionDialogWindow, "Subscribe to Forums dialog was not found");

            // Cancel the dialog window
            cancelButton = subscriptionDialogWindow.Get<Button>("CancelButton");
            Assert.IsNotNull(cancelButton, "Could not find CancelButton on Subscribe to Forums dialog");
            cancelButton.Click();

            // Click the subscribe button again
            actionButton = mainWindow.Get<Button>("SubscribeButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // We should go directly to the Subscription Dialog window this time - no logon dialog
            subscriptionDialogWindow = (Window)mainWindow.ModalWindow("Subscribe to Forums", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(subscriptionDialogWindow, "Subscribe to Forums dialog was not found.");
            subscriptionDialogWindow.Close();
            ExitApp();
        }


        /// <summary>
        /// This test subscribes to the JScript forum using 
        /// workarounds for bugs in White Release 0.17 and then 
        /// verifies that the Subscribe to Forums dialog is not presented
        /// the next time that the user starts the app 
        /// </summary>
        [Test]
        public void SomeSubscriptionsStartupScenario()
        {
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Subscription Dialog should start automatically after logon 
            // because there are no subscriptions.
            GetSubscriptionDialogControls();

            ChangeBrand("Msdn");

            // WORKAROUND - Use filtering to insure that the JScript forum is on screen
            // Release 0.17 has a bug that throws an error if you select 
            // an item that is offscreen. See http://www.codeplex.com/white/WorkItem/View.aspx?WorkItemId=2677
            filterTextBox.Text = "js";

            // Verify that Add and Remove buttons are disabled when no forum is selected
            Assert.IsFalse(addButton.Enabled);
            Assert.IsFalse(removeButton.Enabled);

            Assert.LessOrEqual(1, availableForumsListBox.Rows.Count, "No forums after filtering with js");
            // WORKAROUND - White bug selecting items when there is an image/icon to the left of the title.
            availableForumsListBox.Rows[0].Select();
            availableForumsListBox.Rows[0].Click();

            // After a forum is selected in the availableForumsListBox, the Add button should be enabled but not the Remove button
            Assert.IsTrue(addButton.Enabled);
            Assert.IsFalse(removeButton.Enabled);

            int beforeAddingCount = availableForumsListBox.Rows.Count;

            // Click on the Add button
            addButton.Click();
            Assert.IsFalse(addButton.Enabled);

            // Verify that the forum got moved
            Assert.AreEqual(1, previewForumsListBox.Rows.Count, "Forum was not added to preview list");
            Assert.AreEqual((beforeAddingCount - 1), availableForumsListBox.Rows.Count, "Row COunt suggests the Forum is still in available forums list");
            Assert.AreEqual("JScript for the .NET Framework", previewForumsListBox.Rows[0].Name);
 
            foreach (ListViewRow row in availableForumsListBox.Rows)
            {
                Assert.AreNotEqual("JScript for the .NET Framework", row.Name, "JScript Forum is still in available forums list");
            }

            // Click the Finish button to subscribe to all forums in preview list
            finishButton.Click();

            // Sleep before checking for the forum on main window
            System.Threading.Thread.Sleep(1000);
            Assert.IsTrue(ForumIsSubscribed("JScript for the .NET Framework"), "Could not find JScript forum in subscribed forums");

            ExitApp();

            // Restart the app
            StartApp();

            // Logon
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Looking for the Subscribe to Forums should fail and return null
            subscriptionDialogWindow = (Window)mainWindow.ModalWindow("Subscribe to Forums", Core.Factory.InitializeOption.NoCache);
            Assert.IsNull(subscriptionDialogWindow, "Found Subscribe to Forums at startup with subscribed forums");

            ExitApp();
        }

        /// <summary>
        /// This test verifies that the user can successfully subscribe to multiple forums for 
        /// multiple brands and locales and that the features of the Subscribe to Forums 
        /// dialog function correctly. 
        /// </summary>
        [Test]
        public void MultipleForumsBrandsAndLocalesScenario()
        {
            // Logon 
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Subscription Dialog should start automatically after logon 
            // because there are no subscriptions.
            GetSubscriptionDialogControls();

            // Set number of days to download to 1 day
            daysComboBox.Enter("1");

            // Add 2 MSDN forums to the preview list
            string[] msdnForums = { "JScript for the .NET Framework", "Windows Presentation Foundation (WPF)", };
            ChangeBrand("Msdn");
            AddBrandForumsToPreviewList(msdnForums);

            // Change brand to Microsoft and add 3 forums to the preview list
            string[] microsoftBrandForums = { "Announcements for all Forums", "Communities Sandbox", "Suggestions and Feedback for the Forums", };
            ChangeBrand("Microsoft");
            AddBrandForumsToPreviewList(microsoftBrandForums);

            // Change brand to Expression and add 2 forums to the preview list
            string[] expressionBrandForums = { "Expression Web", "Expression Blend", };
            filterTextBox.Text = "";
            ChangeBrand("Expression");
            AddBrandForumsToPreviewList(expressionBrandForums);

            // Remove 2 forums from preview list
            RemoveForumFromPreviewList("Expression Web");
            RemoveForumFromPreviewList("Communities Sandbox");

            // Expression Web should go back into the available forums list
            // because the brand is still selected
            filterTextBox.Text = "Expression Web";
            Assert.IsTrue(ForumIsInAvailableForumsList("Expression Web"), "Expression Web forum is not in available forums list");
 
            // Communities Sandbox should not go back into the available forums list 
            // because Microsoft brand is not selected
            filterTextBox.Text = "Communities Sandbox";
            Assert.IsFalse(ForumIsInAvailableForumsList("Communities Sandbox"), "Communities Sandbox forum unexpectedly appears in available forums list");
 
            // Change locale to japan and add 3 MSDN forums to the preview list
            filterTextBox.Text = "";
            localeComboBox.Select("ja-JP");
            ChangeBrand("Msdn");

            Assert.LessOrEqual(3, availableForumsListBox.Rows.Count, "Less than 3 forums after switching to ja-JP Msdn");

            int jaCount = availableForumsListBox.Rows.Count;

            // Since we are not globalizing the app at this point and I don't read Japanese anyway,
            // the test selects 3 forums that have strings in their names from the US character set.
            AddOtherLocaleForumsToPreviewList("mvp");

            AddOtherLocaleForumsToPreviewList("1");

            AddOtherLocaleForumsToPreviewList("2");

            // Click Finish to subscribe to these forums and then give the app a little
            // time to update the main window
            finishButton = subscriptionDialogWindow.Get<Button>("FinishButton");
            Assert.IsNotNull(finishButton);
            finishButton.Click();
            System.Threading.Thread.Sleep(1000);

            string[] finalSubscribedForums = { 
                                                 "JScript for the .NET Framework", "Windows Presentation Foundation (WPF)", 
                                                 "Announcements for all Forums", "Suggestions and Feedback for the Forums",
                                                 "Expression Blend", 
                                             };

            // Verify that all the en-US forums are in the main window's subscribed forums view 
            foreach(string forumName in finalSubscribedForums)
            {
                Assert.IsTrue(ForumIsSubscribed(forumName), forumName + " forum was not found in subscribed forums");
            }

            // Since we don't know the fullname of the Japanese locale forums
            // verify that the tree view contains 3 forums with the strings 
            // we used when subscribing to ja-JP forums. Since we didn't subscribe to 
            // any en-US forums with MVP, 1 or 2 in their names, there should be no conflict/confusion

            // Find the TreeView in the left panel
            Core.UIItems.TreeItems.Tree tree = mainWindow.Get<Core.UIItems.TreeItems.Tree>("forumTreeView");
            Assert.IsNotNull(tree);

            int jaForumsCount = 0;

            foreach (Core.UIItems.TreeItems.TreeNode aForumNode in tree.Nodes[0].Nodes[1].Nodes)
            {
                if (aForumNode.Name.Contains("MVP") || aForumNode.Name.Contains("1") || aForumNode.Name.Contains("2"))
                {
                    jaForumsCount++;
                }
            }

            Assert.AreEqual(3, jaForumsCount, "Expected 3 ja-JP forums");

            // Restart the Subscribe to Forums dialog and verify that none of the forums that we
            // subscribed to appear in the available forums list

            StartSubscriptionDialogAndGetControls();

            ChangeBrand("Msdn");
            foreach (string forumName in msdnForums)
            {
                filterTextBox.Text = forumName;
                Assert.IsFalse(ForumIsInAvailableForumsList(forumName), forumName + " was found in available forums list after subscribing to it.");
            }

            ChangeBrand("Microsoft");
            foreach (string forumName in microsoftBrandForums)
            {
                filterTextBox.Text = forumName;
                // We didn't subscribe to "Communities Sandbox" so exclude it from the negative check
                // and do a positive check instead
                if (forumName.Equals("Communities Sandbox"))
                {
                    Assert.IsTrue(ForumIsInAvailableForumsList(forumName), forumName + " was not found in available forums list after removing to it from preview list and reopening subscribe dialog.");
                }
                else
                {
                    Assert.IsFalse(ForumIsInAvailableForumsList(forumName), forumName + " was found in available forums list after subscribing to it.");
                }
            }

            ChangeBrand("Expression");
            foreach (string forumName in expressionBrandForums)
            {
                filterTextBox.Text = forumName;
                if (forumName.Equals("Expression Web"))
                {
                    Assert.IsTrue(ForumIsInAvailableForumsList(forumName), forumName + " was not found in available forums list after removing to it from preview list and reopening subscribe dialog.");
                }
                else
                {
                    Assert.IsFalse(ForumIsInAvailableForumsList(forumName), forumName + " was found in available forums list after subscribing to it.");
                }
            }

            localeComboBox.Select("ja-JP");
            ChangeBrand("Msdn");
            filterTextBox.Text = "";

            Assert.LessOrEqual((jaCount - 3), availableForumsListBox.Rows.Count, "Incorrect forums count after switching to ja-JP Msdn");
            foreach (ListViewRow row in availableForumsListBox.Rows)
            {
                Assert.IsFalse(row.Name.Contains("1") || row.Name.Contains("2"), "Found unexpected ja-JP forum");
            }

            cancelButton.Click();

            System.Threading.Thread.Sleep(500);

            ExitApp();
        }

        #endregion

        #region Private Methods
        /// <summary>
        /// Determines whether or not the specified forum is currently in the preview list
        /// </summary>
        /// <param name="forumName"></param>
        /// <returns>true if found; false otherwise</returns>
        private bool ForumIsInPreviewList(string forumName)
        {
            bool returnValue = false;
            foreach (ListViewRow row in previewForumsListBox.Rows)
            {
                if (row.Name.Equals(forumName))
                {
                    returnValue = true;
                    break;
                }
            }
            return returnValue;
        }

        /// <summary>
        /// Determines whether or not the specified forum is displayed
        /// in the current available forums list. The display is affected 
        /// by brand and locale selections as well as filtering.
        /// </summary>
        /// <param name="forumName"></param>
        /// <returns></returns>
        private bool ForumIsInAvailableForumsList(string forumName)
        {
            bool returnValue = false;
            foreach (ListViewRow row in availableForumsListBox.Rows)
            {
                if (row.Name.Equals(forumName))
                {
                    returnValue = true;
                    break;
                }
            }
            return returnValue;
        }


        /// <summary>
        /// Start the App and get the main window
        /// </summary>
        private void StartApp()
        {
            applicationUnderTest = Application.Launch("ForumsClient.exe");
            mainWindow = (Window)applicationUnderTest.GetWindow(UITestSuiteStringResourceFile.MicrosoftForumsClientBuildName, Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(mainWindow);
        }

        /// <summary>
        /// Clicks the Subscribe Button and locates controls on Subscribe to Forums dialog
        /// </summary>
        private void StartSubscriptionDialogAndGetControls()
        {
            // Start the Subscription Dialog
            Button subscriptionDialogButton = mainWindow.Get<Button>("SubscribeButton");
            Assert.IsNotNull(subscriptionDialogButton, "Could not find SubscribeButton");
            subscriptionDialogButton.Click();

            // Sleep 5 seconds to give the window time to show up
            System.Threading.Thread.Sleep(5000);
            GetSubscriptionDialogControls();
        }

        /// <summary>
        /// Locates all the controls in Subscribe to Forums dialog
        /// </summary>
        private void GetSubscriptionDialogControls()
        {
            // Find the Subscription Dialog window
            subscriptionDialogWindow = (Window)mainWindow.ModalWindow("Subscribe to Forums", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(subscriptionDialogWindow, "Could not find Subscribe to Forums window");

            // Find the listbox controls for the forums on the Subscription Dialog window
            availableForumsListBox = subscriptionDialogWindow.Get<ListView>("AvailableForumsListView");
            Assert.IsNotNull(availableForumsListBox, "Could not find AvailableForumsListView");
            previewForumsListBox = subscriptionDialogWindow.Get<ListView>("PreviewForumsListView");
            Assert.IsNotNull(previewForumsListBox, "Could not find PreviewForumsListView");

            // Find the combobox controls on the Subscription Dialog window
            localeComboBox = subscriptionDialogWindow.Get<ComboBox>("LocaleComboBox");
            Assert.IsNotNull(localeComboBox, "Could not find LocaleComboBox");

            // Wait for the window to finish loading the brands and locales
            while (localeComboBox.Enabled == false)
            {
                System.Threading.Thread.Sleep(500);
            }

            daysComboBox = subscriptionDialogWindow.Get<ComboBox>("DaysComboBox");
            Assert.IsNotNull(daysComboBox, "Could not find DaysComboBox");

            Assert.IsNotNull(subscriptionDialogWindow);

            brandComboBox = subscriptionDialogWindow.Get<ComboBox>("BrandComboBox");
            Assert.IsNotNull(brandComboBox, "Could not find BrandComboBox");

            showComboBox = subscriptionDialogWindow.Get<ComboBox>("ShowComboBox");
            Assert.IsNotNull(showComboBox, "Could not find ShowComboBox");

            filterTextBox = subscriptionDialogWindow.Get<TextBox>("FilterTextBox");
            Assert.IsNotNull(filterTextBox, "Could not find FilterTextBox");

            // Find the button controls on the Subscription Dialog window
            cancelButton = subscriptionDialogWindow.Get<Button>("CancelButton");
            Assert.IsNotNull(cancelButton, "Could not find CancelButton");

            finishButton = subscriptionDialogWindow.Get<Button>("FinishButton");
            Assert.IsNotNull(finishButton, "Could not find FinishButton");

            addButton = subscriptionDialogWindow.Get<Button>("AddButton");
            Assert.IsNotNull(addButton, "Could not find AddButton");

            removeButton = subscriptionDialogWindow.Get<Button>("RemoveButton");
            Assert.IsNotNull(removeButton, "Could not find RemoveButton");

        }

        /// <summary>
        /// Verifies that all the expected forums are found in the filtering tests 
        /// </summary>
        /// <param name="forumNames"></param>
        /// <param name="categoryName"></param>
        private void CheckExpectedForumNames(string[] forumNames, string categoryName)
        {
            int numberOfMatches = 0;
            Assert.LessOrEqual(forumNames.Length, availableForumsListBox.Rows.Count, categoryName + " Row Count");
            foreach (string forumName in forumNames)
            {
                foreach (ListViewRow row in availableForumsListBox.Rows)
                {
                    if (row.Name.Equals(forumName))
                    {
                        numberOfMatches++;
                        break;
                    }
                }
            }

            Assert.AreEqual(forumNames.Length, numberOfMatches, "Not all expected" + categoryName + " forums were found.");
        }

        /// <summary>
        /// Uses Options Dialog to disable Auto Synchronization of Forums.
        /// </summary>
        private void DisableAutoSynch()
        {
            Window optionsDialogWindow;
            Button actionButton;
            CheckBox checkBox;

            StartApp();

            // Cancel logon so we don't get the subscription dialog 
            UITestHelperClass.CancelLogon(mainWindow);

            // Find and click the Options button
            actionButton = mainWindow.Get<Button>("OptionsButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Find the OptionsDialog Window
            optionsDialogWindow = mainWindow.ModalWindow("OptionsDialog", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(optionsDialogWindow);

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);

            // Turn off automatic synchronization
            checkBox.Click();
            Assert.IsFalse(checkBox.Checked);

            // Save the option
            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            mainWindow.Close();

        }

        /// <summary>
        /// Remove the forum specified by forumName parameter from subscribed forums list by clicking 
        /// Unsubscribe in context menu
        /// 
        /// This does not work due to White bug # 3075
        /// http://www.codeplex.com/white/WorkItem/View.aspx?WorkItemId=3075
        /// When the bug is fixed, calls to UnsubscribeForum should be added to the end of each test
        /// that subscribes to forums.
        /// </summary>
        /// <param name="forumName"></param>
        private void UnsubscribeForum(string forumName)
        {

            // Find the TreeView in the left panel
            Core.UIItems.TreeItems.Tree tree = mainWindow.Get<Core.UIItems.TreeItems.Tree>("forumTreeView");
            Assert.IsNotNull(tree);

            // Find the specified forum
            Core.UIItems.TreeItems.TreeNode aForumNode = tree.Nodes[0].Nodes[1].Nodes.GetItem(forumName);
            if (aForumNode != null)
            {
                Assert.IsTrue(aForumNode.Name.Equals(forumName));
                // Right click failed to bring up context menu without the focus - White bug
                aForumNode.Select();
                aForumNode.RightClick();
                System.Threading.Thread.Sleep(500);
                Assert.IsTrue(mainWindow.HasPopup(), "No context menu after right click");

                // Click Unsubscribe
                Core.UIItems.MenuItems.Menu menu = mainWindow.PopupMenu("Unsubscribe");
                Assert.IsNotNull(menu, "Unsubscribe is not in context menu");
                menu.Click();
                System.Threading.Thread.Sleep(500);

                // Verify that the forum is not in the subscribed list anymore.
                Assert.IsNull(tree.Nodes[0].Nodes[1].Nodes.GetItem(forumName));
            }
        }

        /// <summary>
        /// Remove the first forum that has a name containing
        /// the filterString parameter from subscribed forums list by clicking 
        /// Unsubscribe in context menu  
        /// 
        /// This method currently throws an exception due to White bug 3075
        /// http://www.codeplex.com/white/WorkItem/View.aspx?WorkItemId=3075
        /// When the bug is fixed, calls to UnsubscribeOtherLocaleForum shoudl be added to the end of each test
        /// that subscribes to forums in locales other than en-US.
        /// </summary>
        /// <param name="filterString"></param>
        private void UnsubscribeOtherLocaleForum(string filterString)
        {
                  // Find the TreeView in the left panel
            Core.UIItems.TreeItems.Tree tree = mainWindow.Get<Core.UIItems.TreeItems.Tree>("forumTreeView");
            Assert.IsNotNull(tree);

            // Find the specified forum
            foreach (Core.UIItems.TreeItems.TreeNode aForumNode in tree.Nodes[0].Nodes[1].Nodes)
            {
                if (aForumNode.Name.Contains(filterString))
                {
                    aForumNode.Focus();
                    aForumNode.RightClick();
                    System.Threading.Thread.Sleep(500);
                    Assert.IsTrue(mainWindow.HasPopup(), "No context menu after right click");

                    // Click Unsubscribe
                    Core.UIItems.MenuItems.Menu menu = mainWindow.PopupMenu("Unsubscribe");
                    Assert.IsNotNull(menu, "Unsubscribe is not in context menu");
                    menu.Click();
                    System.Threading.Thread.Sleep(500);
                }
            }
        }

        /// <summary>
        /// Determine whether or not the specified forum appears 
        /// in the main window's subscribed forum view
        /// </summary>
        /// <param name="forumName"></param>
        /// <returns></returns>
        private bool ForumIsSubscribed(string forumName)
        {
            bool returnValue = false;

            // Find the TreeView in the left panel
            Core.UIItems.TreeItems.Tree tree = mainWindow.Get<Core.UIItems.TreeItems.Tree>("forumTreeView");
            Assert.IsNotNull(tree);

            // This is the only way to get to the "Forums" node of the TreeView
            // Ideally, we'd be able to tell White to get "Forums" from the 
            // TreeView but, because we have StackPanel objects as the 
            // header property, WPF and UIAutomation don't cooperate.
            // Forunately, we have a standard order of items in the 
            // TreeView down to the Forums header
            Core.UIItems.TreeItems.TreeNode aForumNode;

            aForumNode = tree.Nodes[0].Nodes[1].Nodes.GetItem(forumName);
            if (aForumNode != null)
            {
                returnValue = true;
            }

            return returnValue;
        }

        /// <summary>
        /// Workaround White bug that does not select rows in a list
        /// if the items contain images to the left of the search field
        /// http://www.codeplex.com/white/WorkItem/View.aspx?WorkItemId=2677
        /// </summary>
        /// <param name="forumName"></param>
        /// <returns></returns>
        private bool SelectRowInAvailableForums(string forumName)
        {
            bool returnValue = false;
            foreach (ListViewRow row in availableForumsListBox.Rows)
            {
                if (row.Name.Equals(forumName ))
                {
                    row.Select();
                    row.Click();
                    returnValue = true;
                    break;
                }
            }
            return returnValue;
        }


        /// <summary>
        /// Select forums in available forums list and click Add button to
        /// move them to the preview list
        /// </summary>
        /// <param name="forumNames"></param>
        private void AddBrandForumsToPreviewList(string[] forumNames)
        {
            foreach (string forumName in forumNames)
            {
                // 
                // White Release 0.17 has bugs in its listbox single and multi selection methods so the test has to 
                // filter to guarantee that the forum is on screen and click 
                // the Add button for each forum. When the bugs are fixed, the filtering should be removed
                // and the selection shoudl be changed to multi-select all forums in the 
                // forumNames array before clicking Add exactly once per brand.
                // See http://www.codeplex.com/white/WorkItem/View.aspx?WorkItemId=2783
                //
                filterTextBox.Text = forumName;

                Assert.IsTrue(SelectRowInAvailableForums(forumName), "Could not select " + forumName + " forum");
                Assert.IsTrue(addButton.Enabled, "Add button is NOT enabled with a forum selected");

                addButton.Click();
                expectedPreviewListCount++;
                Assert.AreEqual(expectedPreviewListCount, previewForumsListBox.Rows.Count, "Expected " + expectedPreviewListCount + " forums in preview list");
                Assert.IsTrue(ForumIsInPreviewList(forumName), forumName + " forum not in preview list");
                Assert.IsFalse(ForumIsInAvailableForumsList(forumName), forumName + " forum is still in available forums list");
            }
        }

        /// <summary>
        /// Use a filter string to select items from other locale brand combinations
        /// Just selects the first item that includes the string in its name
        /// </summary>
        /// <param name="filterString"></param>
        private void AddOtherLocaleForumsToPreviewList(string filterString)
        {
            filterTextBox.Text = filterString;
            availableForumsListBox.Rows[0].Select();
            availableForumsListBox.Rows[0].Click();
            Assert.IsTrue(addButton.Enabled);
            addButton.Click();
        }

        /// <summary>
        /// Clicks the Remove button to remove a forum from the preview list 
        /// and move it back to the available forums list if appropriate 
        /// </summary>
        /// <param name="forumName"></param>
        private void RemoveForumFromPreviewList(string forumName)
        {
            foreach (ListViewRow row in previewForumsListBox.Rows)
            {
                if (row.Name.Equals(forumName))
                {
                    row.Select();
                    row.Click();
                    Assert.IsTrue(removeButton.Enabled, "Remove button is not enabled with a  preview list forum selected");
                    Assert.IsFalse(addButton.Enabled, "Add button is enabled with a  preview list forum selected");
                    removeButton.Click();
                    expectedPreviewListCount--;
                    Assert.IsFalse(ForumIsInPreviewList(forumName), forumName + " forum is still in preview list");
                    break;
                }
            }
        }

        /// <summary>
        /// Changes the brand name in the combobox
        /// and waits to give time to download the data 
        /// over the internet
        /// </summary>
        /// <param name="brandName"></param>
        private void ChangeBrand(string brandName)
        {

            brandComboBox.Select(brandName);
            System.Threading.Thread.Sleep(testParameters.PostBrandOrLocaleChangeSleepInterval);
        }

        /// <summary>
        /// Close's applications main window and sleeps to give it time to exit gracefully
        /// </summary>
        private void ExitApp()
        {
            mainWindow.Close();
            // Sleep so that the app has time to exit before the TearDown method runs
            System.Threading.Thread.Sleep(1000);
        }

        #endregion
    }

}
